<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.9.1"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Eigen: Quick reference guide for sparse matrices</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
</script>
<script type="text/javascript" async="async" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="eigendoxy.css" rel="stylesheet" type="text/css">
<!--  -->
<script type="text/javascript" src="eigen_navtree_hacks.js"></script>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="Eigen_Silly_Professor_64x64.png"/></td>
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname"><a href="http://eigen.tuxfamily.org">Eigen</a>
   &#160;<span id="projectnumber">3.4.90 (git rev 67eeba6e720c5745abc77ae6c92ce0a44aa7b7ae)</span>
   </div>
  </td>
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.svg"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.1 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('group__SparseQuickRefPage.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">Quick reference guide for sparse matrices<div class="ingroups"><a class="el" href="group__Sparse__chapter.html">Sparse linear algebra</a></div></div>  </div>
</div><!--header-->
<div class="contents">
<hr  />
<p>In this page, we give a quick summary of the main operations available for sparse matrices in the class <a class="el" href="classEigen_1_1SparseMatrix.html" title="A versatible sparse matrix representation.">SparseMatrix</a>. First, it is recommended to read the introductory tutorial at <a class="el" href="group__TutorialSparse.html">Sparse matrix manipulations</a>. The important point to have in mind when working on sparse matrices is how they are stored : i.e either row major or column major. The default is column major. Most arithmetic operations on sparse matrices will assert that they have the same storage order.</p>
<h1><a class="anchor" id="SparseMatrixInit"></a>
Sparse Matrix Initialization</h1>
<table class="manual">
<tr>
<th>Category  </th><th>Operations </th><th>Notes </th></tr>
<tr>
<td>Constructor </td><td><div class="fragment"><div class="line">SparseMatrix&lt;double&gt; sm1(1000,1000); </div>
<div class="line">SparseMatrix&lt;std::complex&lt;double&gt;,<a class="code" href="group__enums.html#ggaacded1a18ae58b0f554751f6cdf9eb13a77c993a8d9f6efe5c1159fb2ab07dd4f">RowMajor</a>&gt; sm2;</div>
<div class="ttc" id="agroup__enums_html_ggaacded1a18ae58b0f554751f6cdf9eb13a77c993a8d9f6efe5c1159fb2ab07dd4f"><div class="ttname"><a href="group__enums.html#ggaacded1a18ae58b0f554751f6cdf9eb13a77c993a8d9f6efe5c1159fb2ab07dd4f">Eigen::RowMajor</a></div><div class="ttdeci">@ RowMajor</div><div class="ttdef"><b>Definition:</b> Constants.h:323</div></div>
</div><!-- fragment -->  </td><td>Default is ColMajor  </td></tr>
<tr class="alt">
<td>Resize/Reserve </td><td><div class="fragment"><div class="line">sm1.resize(m,n);      <span class="comment">// Change sm1 to a m x n matrix.</span></div>
<div class="line">sm1.reserve(nnz);     <span class="comment">// Allocate room for nnz nonzeros elements.   </span></div>
</div><!-- fragment -->  </td><td>Note that when calling reserve(), it is not required that nnz is the exact number of nonzero elements in the final matrix. However, an exact estimation will avoid multiple reallocations during the insertion phase.   </td></tr>
<tr>
<td>Assignment  </td><td><div class="fragment"><div class="line"> SparseMatrix&lt;double,Colmajor&gt; sm1;</div>
<div class="line"><span class="comment">// Initialize sm2 with sm1.</span></div>
<div class="line"> SparseMatrix&lt;double,Rowmajor&gt; sm2(sm1), sm3;        </div>
<div class="line"> <span class="comment">// Assignment and evaluations modify the storage order.</span></div>
<div class="line"> sm3 = sm1; </div>
</div><!-- fragment -->  </td><td>The copy constructor can be used to convert from a storage order to another  </td></tr>
<tr class="alt">
<td>Element-wise Insertion </td><td><div class="fragment"><div class="line"><span class="comment">// Insert a new element; </span></div>
<div class="line"> sm1.insert(i, j) = v_ij;  </div>
<div class="line"> </div>
<div class="line"><span class="comment">// Update the value v_ij</span></div>
<div class="line"> sm1.coeffRef(i,j) = v_ij;</div>
<div class="line"> sm1.coeffRef(i,j) += v_ij;</div>
<div class="line"> sm1.coeffRef(i,j) -= v_ij;</div>
</div><!-- fragment -->  </td><td>insert() assumes that the element does not already exist; otherwise, use coeffRef()  </td></tr>
<tr>
<td>Batch insertion </td><td><div class="fragment"><div class="line">std::vector&lt; Eigen::Triplet&lt;double&gt; &gt; tripletList;</div>
<div class="line">tripletList.reserve(estimation_of_entries);</div>
<div class="line"><span class="comment">// -- Fill tripletList with nonzero elements...</span></div>
<div class="line">sm1.setFromTriplets(TripletList.begin(), TripletList.end());</div>
</div><!-- fragment -->  </td><td>A complete example is available at <a class="el" href="group__TutorialSparse.html#TutorialSparseFilling">Triplet Insertion </a>.  </td></tr>
<tr class="alt">
<td>Constant or Random Insertion </td><td><div class="fragment"><div class="line">sm1.setZero();</div>
</div><!-- fragment -->  </td><td>Remove all non-zero coefficients  </td></tr>
</table>
<h1><a class="anchor" id="SparseBasicInfos"></a>
Matrix properties</h1>
<p>Beyond the basic functions rows() and cols(), there are some useful functions that are available to easily get some information from the matrix. </p><table class="manual">
<tr>
<td><div class="fragment"><div class="line">sm1.rows();         <span class="comment">// Number of rows</span></div>
<div class="line">sm1.cols();         <span class="comment">// Number of columns </span></div>
<div class="line">sm1.nonZeros();     <span class="comment">// Number of non zero values   </span></div>
<div class="line">sm1.outerSize();    <span class="comment">// Number of columns (resp. rows) for a column major (resp. row major )</span></div>
<div class="line">sm1.innerSize();    <span class="comment">// Number of rows (resp. columns) for a row major (resp. column major)</span></div>
<div class="line">sm1.norm();         <span class="comment">// Euclidian norm of the matrix</span></div>
<div class="line">sm1.squaredNorm();  <span class="comment">// Squared norm of the matrix</span></div>
<div class="line">sm1.blueNorm();</div>
<div class="line">sm1.isVector();     <span class="comment">// Check if sm1 is a sparse vector or a sparse matrix</span></div>
<div class="line">sm1.isCompressed(); <span class="comment">// Check if sm1 is in compressed form</span></div>
<div class="line">...</div>
</div><!-- fragment -->   </td></tr>
</table>
<h1><a class="anchor" id="SparseBasicOps"></a>
Arithmetic operations</h1>
<p>It is easy to perform arithmetic operations on sparse matrices provided that the dimensions are adequate and that the matrices have the same storage order. Note that the evaluation can always be done in a matrix with a different storage order. In the following, <b>sm</b> denotes a sparse matrix, <b>dm</b> a dense matrix and <b>dv</b> a dense vector. </p><table class="manual">
<tr>
<th>Operations  </th><th>Code  </th><th><p class="starttd">Notes </p>
<p class="endtd"></p>
</th></tr>
<tr>
<td>add subtract  </td><td><div class="fragment"><div class="line">sm3 = sm1 + sm2; </div>
<div class="line">sm3 = sm1 - sm2;</div>
<div class="line">sm2 += sm1; </div>
<div class="line">sm2 -= sm1; </div>
</div><!-- fragment -->  </td><td><p class="starttd">sm1 and sm2 should have the same storage order  </p>
<p class="endtd"></p>
</td></tr>
<tr class="alt">
<td>scalar product</td><td><div class="fragment"><div class="line">sm3 = sm1 * s1;   sm3 *= s1; </div>
<div class="line">sm3 = s1 * sm1 + s2 * sm2; sm3 /= s1;</div>
</div><!-- fragment -->  </td><td><p class="starttd">Many combinations are possible if the dimensions and the storage order agree. </p>
<p class="endtd"></p>
</td></tr>
<tr>
<td>Sparse Product  </td><td><div class="fragment"><div class="line">sm3 = sm1 * sm2;</div>
<div class="line">dm2 = sm1 * dm1;</div>
<div class="line">dv2 = sm1 * dv1;</div>
</div><!-- fragment -->  </td><td><p class="starttd"></p>
<p class="endtd"></p>
</td></tr>
<tr class="alt">
<td>transposition, adjoint </td><td><div class="fragment"><div class="line">sm2 = sm1.transpose();</div>
<div class="line">sm2 = sm1.adjoint();</div>
</div><!-- fragment -->  </td><td>Note that the transposition change the storage order. There is no support for transposeInPlace().   </td></tr>
<tr>
<td>Permutation  </td><td><div class="fragment"><div class="line">perm.indices();      <span class="comment">// Reference to the vector of indices</span></div>
<div class="line">sm1.twistedBy(perm); <span class="comment">// Permute rows and columns</span></div>
<div class="line">sm2 = sm1 * perm;    <span class="comment">// Permute the columns</span></div>
<div class="line">sm2 = perm * sm1;    <span class="comment">// Permute the columns</span></div>
</div><!-- fragment -->  </td><td><p class="starttd"></p>
<p class="endtd"></p>
</td></tr>
<tr>
<td>Component-wise ops  </td><td><div class="fragment"><div class="line">sm1.cwiseProduct(sm2);</div>
<div class="line">sm1.cwiseQuotient(sm2);</div>
<div class="line">sm1.cwiseMin(sm2);</div>
<div class="line">sm1.cwiseMax(sm2);</div>
<div class="line">sm1.cwiseAbs();</div>
<div class="line">sm1.cwiseSqrt();</div>
</div><!-- fragment --> </td><td>sm1 and sm2 should have the same storage order   </td></tr>
</table>
<h1><a class="anchor" id="sparseotherops"></a>
Other supported operations</h1>
<table class="manual">
<tr>
<th style="min-width:initial">Code  </th><th>Notes  </th></tr>
<tr>
<td colspan="2">Sub-matrices </td></tr>
<tr>
<td><div class="fragment"><div class="line">sm1.block(startRow, startCol, rows, cols); </div>
<div class="line">sm1.block(startRow, startCol); </div>
<div class="line">sm1.topLeftCorner(rows, cols); </div>
<div class="line">sm1.topRightCorner(rows, cols);</div>
<div class="line">sm1.bottomLeftCorner( rows, cols);</div>
<div class="line">sm1.bottomRightCorner( rows, cols);</div>
</div><!-- fragment --> </td><td>Contrary to dense matrices, here <b>all these methods are read-only</b>.<br  />
See <a class="el" href="group__TutorialSparse.html#TutorialSparse_SubMatrices">Block operations</a> and below for read-write sub-matrices.   </td></tr>
<tr class="alt">
<td colspan="2">Range  </td></tr>
<tr class="alt">
<td><div class="fragment"><div class="line">sm1.innerVector(outer);           <span class="comment">// RW</span></div>
<div class="line">sm1.innerVectors(start, size);    <span class="comment">// RW</span></div>
<div class="line">sm1.leftCols(size);               <span class="comment">// RW</span></div>
<div class="line">sm2.rightCols(size);              <span class="comment">// RO because sm2 is row-major</span></div>
<div class="line">sm1.middleRows(start, numRows);   <span class="comment">// RO because sm1 is column-major</span></div>
<div class="line">sm1.middleCols(start, numCols);   <span class="comment">// RW</span></div>
<div class="line">sm1.col(j);                       <span class="comment">// RW</span></div>
</div><!-- fragment -->  </td><td>A inner vector is either a row (for row-major) or a column (for column-major).<br  />
As stated earlier, for a read-write sub-matrix (RW), the evaluation can be done in a matrix with different storage order.   </td></tr>
<tr>
<td colspan="2">Triangular and selfadjoint views </td></tr>
<tr>
<td><div class="fragment"><div class="line">sm2 = sm1.triangularview&lt;<a class="code" href="group__enums.html#gga39e3366ff5554d731e7dc8bb642f83cdaf581029282d421eee5aae14238c6f749">Lower</a>&gt;();</div>
<div class="line">sm2 = sm1.selfadjointview&lt;<a class="code" href="group__enums.html#gga39e3366ff5554d731e7dc8bb642f83cdaf581029282d421eee5aae14238c6f749">Lower</a>&gt;();</div>
<div class="ttc" id="agroup__enums_html_gga39e3366ff5554d731e7dc8bb642f83cdaf581029282d421eee5aae14238c6f749"><div class="ttname"><a href="group__enums.html#gga39e3366ff5554d731e7dc8bb642f83cdaf581029282d421eee5aae14238c6f749">Eigen::Lower</a></div><div class="ttdeci">@ Lower</div><div class="ttdef"><b>Definition:</b> Constants.h:211</div></div>
</div><!-- fragment -->  </td><td>Several combination between triangular views and blocks views are possible <div class="fragment"></div><!-- fragment -->   </td></tr>
<tr class="alt">
<td colspan="2">Triangular solve  </td></tr>
<tr class="alt">
<td><div class="fragment"><div class="line">dv2 = sm1.triangularView&lt;<a class="code" href="group__enums.html#gga39e3366ff5554d731e7dc8bb642f83cdafca2ccebb604f171656deb53e8c083c1">Upper</a>&gt;().solve(dv1);</div>
<div class="line">dv2 = sm1.topLeftCorner(size, size)</div>
<div class="line">         .triangularView&lt;<a class="code" href="group__enums.html#gga39e3366ff5554d731e7dc8bb642f83cdaf581029282d421eee5aae14238c6f749">Lower</a>&gt;().solve(dv1);</div>
<div class="ttc" id="agroup__enums_html_gga39e3366ff5554d731e7dc8bb642f83cdafca2ccebb604f171656deb53e8c083c1"><div class="ttname"><a href="group__enums.html#gga39e3366ff5554d731e7dc8bb642f83cdafca2ccebb604f171656deb53e8c083c1">Eigen::Upper</a></div><div class="ttdeci">@ Upper</div><div class="ttdef"><b>Definition:</b> Constants.h:213</div></div>
</div><!-- fragment -->  </td><td>For general sparse solve, Use any suitable module described at <a class="el" href="group__TopicSparseSystems.html">Solving Sparse Linear Systems</a>   </td></tr>
<tr>
<td colspan="2">Low-level API </td></tr>
<tr>
<td><div class="fragment"><div class="line">sm1.valuePtr();      <span class="comment">// Pointer to the values</span></div>
<div class="line">sm1.innerIndexPtr();  <span class="comment">// Pointer to the indices.</span></div>
<div class="line">sm1.outerIndexPtr(); <span class="comment">// Pointer to the beginning of each inner vector</span></div>
</div><!-- fragment -->  </td><td>If the matrix is not in compressed form, <code>makeCompressed()</code> should be called before.<br  />
Note that these functions are mostly provided for interoperability purposes with external libraries.<br  />
A better access to the values of the matrix is done by using the InnerIterator class as described in <a class="el" href="group__TutorialSparse.html">the Tutorial Sparse </a> section  </td></tr>
<tr class="alt">
<td colspan="2">Mapping external buffers </td></tr>
<tr class="alt">
<td><div class="fragment"><div class="line"><span class="keywordtype">int</span> outerIndexPtr[cols+1];</div>
<div class="line"><span class="keywordtype">int</span> innerIndices[nnz];</div>
<div class="line"><span class="keywordtype">double</span> values[nnz];</div>
<div class="line">Map&lt;SparseMatrix&lt;double&gt; &gt; sm1(rows,cols,nnz,outerIndexPtr, <span class="comment">// read-write</span></div>
<div class="line">                               innerIndices,values);</div>
<div class="line">Map&lt;const SparseMatrix&lt;double&gt; &gt; sm2(...);                  <span class="comment">// read-only</span></div>
</div><!-- fragment -->  </td><td>As for dense matrices, class <a class="el" href="classEigen_1_1Map_3_01SparseMatrixType_01_4.html" title="Specialization of class Map for SparseMatrix-like storage.">Map&lt;SparseMatrixType&gt;</a> can be used to see external buffers as an Eigen's <a class="el" href="classEigen_1_1SparseMatrix.html" title="A versatible sparse matrix representation.">SparseMatrix</a> object.   </td></tr>
</table>
</div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Thu Apr 21 2022 13:07:55 for Eigen by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.9.1 </li>
  </ul>
</div>
</body>
</html>
